﻿using AutoMapper;
using Lazy.Captcha.Core;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Server.IISIntegration;
using Microsoft.Extensions.Configuration;
using Mysqlx.Crud;
using Panda.DynamicWebApi;
using Panda.DynamicWebApi.Attributes;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WareHose.Application.Admins.Dto;
using WareHose.Application.Warehouse.Dto;
using WareHouse.DB.AllDbContext;
using WareHouse.Domain;
using WareHouse.Domain.Warehouses;
using WareHouse.Repositories;

namespace WareHose.Application.Warehouse
{
    /// <summary>
    /// 仓库管理
    /// </summary>
    [DynamicWebApi]
    [ApiExplorerSettings(GroupName = "v2")]
    public class WarehouseService : IDynamicWebApi
    {
        private readonly IBaseRepository<Warehouse1> wareHouse;
        private readonly IBaseRepository<WarehouseType> wareHouseType;
        private readonly IBaseRepository<LocationType> locationType;
        private readonly IBaseRepository<Location> location;
        private readonly IMapper mapper;
        private readonly ISqlSugarClient db;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="wareHouse"></param>
        /// <param name="mapper"></param>
        /// <param name="db"></param>
        public WarehouseService(IBaseRepository<Warehouse1> wareHouse, IMapper mapper, ISqlSugarClient db, IBaseRepository<WarehouseType> wareHouseType, IBaseRepository<Location> location, IBaseRepository<LocationType> locationType)
        {
            this.wareHouse = wareHouse;
            this.mapper = mapper;
            this.db = db;
            this.wareHouseType = wareHouseType;
            this.location = location;
            this.locationType = locationType;
        }

        #region 仓库管理
        /// <summary>
        /// 显示仓库分类
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ResultDto<List<WarehouseType>>> ShowWarehouseType()
        {
            try
            {
                var list = await wareHouseType.QueryAsync();
                return new ResultDto<List<WarehouseType>>
                {
                    Code = Status.Success,
                    Data = list
                };
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 仓库显示分页
        /// </summary>
        /// <param name="warehouseCode"></param>
        /// <param name="warehouseName"></param>
        /// <param name="warehouseTypeId"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ResultDto<PagingDto<WarehouseDto>>> ShowWarehouse(string warehouseCode, string warehouseName, int? warehouseTypeId,int pageIndex=1,int pageSize=10)
        {
            try
            {
                var list = await db.Queryable<Warehouse1,WarehouseType>((a,b)=>new JoinQueryInfos(
                    JoinType.Left,a.WarehouseTypeId==b.WarehouseTypeId
                    ))
                    .Where(a => a.IsDel == false)
                    .Select((a, b) => new WarehouseDto
                    {
                        WarehouseId = a.WarehouseId.ToString(),
                        WarehouseCode = a.WarehouseCode,
                        WarehouseName = a.WarehouseName,
                        LeaseTime = a.LeaseTime,
                        WarehouseTypeId = a.WarehouseTypeId,
                        WarehouseTypeName = b.WarehouseTypeName,
                        IsDisable = a.IsDisable,
                        IsDefault = a.IsDefault,
                        WarehouseAddress = a.WarehouseAddress,
                        WarehouseArea = a.WarehouseArea,
                        Contacts = a.Contacts,
                        Phone = a.Phone
                    })
                    .WhereIF(!string.IsNullOrEmpty(warehouseCode), a => a.WarehouseCode.Contains(warehouseCode))
                    .WhereIF(!string.IsNullOrEmpty(warehouseName), a => a.WarehouseName.Contains(warehouseName))
                    .WhereIF(warehouseTypeId != null, a => a.WarehouseTypeId == warehouseTypeId)
                    .ToPageListAsync(pageIndex, pageSize);
                return new ResultDto<PagingDto<WarehouseDto>>
                {
                    Code = Status.Success,
                    Data = new PagingDto<WarehouseDto>
                    {
                        TotalRows = list.Count,
                        Rows = list
                    }
                };


                //var exp = Expressionable.Create<Warehouse1>();
                ////查询条件
                //exp.AndIF(!string.IsNullOrEmpty(warehouseCode), x => x.WarehouseCode.Contains(warehouseCode));
                //exp.AndIF(!string.IsNullOrEmpty(warehouseName), x => x.WarehouseName.Contains(warehouseName));
                //exp.AndIF((warehouseTypeId != 0), x => x.WarehouseTypeId == warehouseTypeId);

                ////分页
                //var page = await wareHouse.PageAsync(pageIndex, pageSize, exp.ToExpression());

                //return new ResultDto<PagingDto<Warehouse1>>
                //{
                //    Code = Status.Success,
                //    Message = "成功",
                //    Data = new PagingDto<Warehouse1>
                //    {
                //        TotalRows = page.Item1,
                //        Rows = page.Item2,
                //    }
                //};
            }
            catch (Exception)
            {
               
                throw;
            }
        }

        /// <summary>
        /// 添加仓库
        /// </summary>
        /// <param name="warehouseInfo">添加仓库信息</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResultDto> AddWarehouse(AddUpdWarehouseDto warehouseInfo)
        {
            try
            {
                var ware = await wareHouse.FistAsync(x=>x.WarehouseName==warehouseInfo.WarehouseName);
                if (ware != null)
                {
                    return new ResultDto { Code = Status.Failed, Message = "仓库名称重复" };
                }
                else
                {
                    var entity = mapper.Map<AddUpdWarehouseDto, Warehouse1>(warehouseInfo);
                    await wareHouse.InsertAsync(entity);
                    return new ResultDto { Code = Status.Success, Message = "添加成功" };
                }
            }
            catch (Exception e)
            {
                return new ResultDto { Code = Status.Failed, Message = e.Message };
            }
        }

        /// <summary>
        /// 反填仓库
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ResultDto<WarehouseDto>> BackFillWarehouse(long id)
        {
            try
            {
                var info = await wareHouse.FistAsync(x=>x.WarehouseId==id);
                var warehouseDto = mapper.Map<WarehouseDto>(info);
                warehouseDto.WarehouseId= warehouseDto.WarehouseId.ToString();
                return new ResultDto<WarehouseDto>
                {
                    Code = Status.Success,
                    Data = warehouseDto
                };
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 修改仓库
        /// </summary>
        /// <param name="warehouseInfo"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<ResultDto> UpdWarehouse(AddUpdWarehouseDto warehouseInfo)
        {
            try
            {
                var ware = await wareHouse.FistAsync(x => x.WarehouseName == warehouseInfo.WarehouseName && x.WarehouseId!=warehouseInfo.WarehouseId);
                if (ware != null)
                {
                    return new ResultDto { Code = Status.Failed, Message = "仓库名称重复" };
                }
                else
                {
                    var entity = mapper.Map<AddUpdWarehouseDto, Warehouse1>(warehouseInfo);
                    await wareHouse.UpdateAsync(entity);
                    return new ResultDto { Code = Status.Success, Message = "修改成功" };
                }
            }
            catch (Exception e)
            {
                return new ResultDto { Code = Status.Failed, Message = e.Message };
            }
        }

        /// <summary>
        /// 逻辑删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete]
        public async Task<ResultDto> DelWarehouse(long id)
        {
            try
            {
                var entity = await wareHouse.FistAsync(x => x.WarehouseId == id);
                if(entity != null)
                {
                    await wareHouse.Delete(id);
                    return new ResultDto
                    {
                        Code = Status.Success,
                        Message = "删除成功"
                    };
                }
                else
                {
                    return new ResultDto
                    {
                        Code = Status.Failed,
                        Message = "删除失败"
                    };
                }
            }
            catch (Exception e)
            {
                return new ResultDto { Code = Status.Failed, Message = e.Message };
            }
        }
        #endregion

        #region 库位管理

        /// <summary>
        /// 显示库位类型
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ResultDto<List<LocationType>>> ShowLocationType()
        {
            try
            {
                var list = await locationType.QueryAsync();
                return new ResultDto<List<LocationType>>
                {
                    Code = Status.Success,
                    Data = list
                };
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 分页查询显示库位
        /// </summary>
        /// <param name="locatoinCode"></param>
        /// <param name="locationName"></param>
        /// <param name="warehouseId"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ResultDto<PagingDto<LocationDto>>> ShowLocation(string locatoinCode, string locationName, string warehouseId, int pageIndex = 1, int pageSize = 10)
        {
            try
            {
                RefAsync<int> total = 0;
                var list = await db.Queryable<Location, LocationType,Warehouse1>((a, b,c) => new JoinQueryInfos(
                    JoinType.Left, a.LocationTypeId == b.LocationTypeId,
                    JoinType.Left,a.WarehouseId==c.WarehouseId
                    ))
                    .Where(a => a.IsDel == false)
                    .Select((a, b,c) => new LocationDto
                    {
                        LocationId = a.LocationId.ToString(),
                        LocationCode = a.LocationCode,
                        LocationName = a.LocationName,
                        LocationTypeName = b.LocationTypeName,
                        WarehouseId = a.WarehouseId.ToString(),
                        WarehouseName = c.WarehouseName,
                        IsDisable = a.IsDisable,
                        IsDefault = a.IsDefault,
                        CreateTime = a.CreateTime,
                        Remark = a.Remark
                    })
                    .WhereIF(!string.IsNullOrEmpty(locatoinCode), a => a.LocationCode.Contains(locatoinCode))
                    .WhereIF(!string.IsNullOrEmpty(locationName), a => a.LocationName.Contains(locationName))
                    .WhereIF(warehouseId != null, a => a.WarehouseId == warehouseId)
                    .ToPageListAsync(pageIndex, pageSize, total);
                return new ResultDto<PagingDto<LocationDto>>
                {
                    Code = Status.Success,
                    Data = new PagingDto<LocationDto>
                    {
                        TotalRows = list.Count,
                        Rows = list
                    }
                };




                //var exp = Expressionable.Create<Location>();
                ////查询条件
                //exp.AndIF(!string.IsNullOrEmpty(locatoinCode), x => x.LocationCode.Contains(locatoinCode));
                //exp.AndIF(!string.IsNullOrEmpty(locationName), x => x.LocationName.Contains(locationName));
                //exp.AndIF((warehouseId != 0), x => x.WarehouseId == warehouseId);

                ////分页
                //var page = await location.PageAsync(pageIndex, pageSize, exp.ToExpression());

                //return new ResultDto<PagingDto<Location>>
                //{
                //    Code = Status.Success,
                //    Message = "成功",
                //    Data = new PagingDto<Location>
                //    {
                //        TotalRows = page.Item1,
                //        Rows = page.Item2,
                //    }
                //};
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 添加库位
        /// </summary>
        /// <param name="locationInfo">添加仓库信息</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResultDto> AddLocation(AddUpdLocationDto locationInfo)
        {
            try
            {
                var entity = mapper.Map<AddUpdLocationDto, Location>(locationInfo);
                await location.InsertAsync(entity);
                return new ResultDto { Code = Status.Success, Message = "添加成功" };
                
            }
            catch (Exception e)
            {
                return new ResultDto { Code = Status.Failed, Message = e.Message };
            }
        }

        /// <summary>
        /// 反填库位
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ResultDto<LocationDto>> BackFillLocation(long id)
        {
            try
            {
                var info = await location.FistAsync(x => x.LocationId == id);
                var locationDto = mapper.Map<LocationDto>(info);
                locationDto.LocationId = locationDto.LocationId.ToString();
                return new ResultDto<LocationDto>
                {
                    Code = Status.Success,
                    Data = locationDto
                };
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 修改库位
        /// </summary>
        /// <param name="locationInfo"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<ResultDto> UpdLocation(AddUpdLocationDto locationInfo)
        {
            try
            {
                var entity = mapper.Map<AddUpdLocationDto, Location>(locationInfo);
                await location.UpdateAsync(entity);
                return new ResultDto { Code = Status.Success, Message = "修改成功" };
                
            }
            catch (Exception e)
            {
                return new ResultDto { Code = Status.Failed, Message = e.Message };
            }
        }

        /// <summary>
        /// 逻辑删除库位
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete]
        public async Task<ResultDto> DelLocation(long id)
        {
            try
            {
                var entity = await location.FistAsync(x => x.LocationId == id);
                if (entity != null)
                {
                    await location.Delete(id);
                    return new ResultDto
                    {
                        Code = Status.Success,
                        Message = "删除成功"
                    };
                }
                else
                {
                    return new ResultDto
                    {
                        Code = Status.Failed,
                        Message = "删除失败"
                    };
                }
                //var res = await location.Delete(id);
                //return new ResultDto
                //{
                //    Code = Status.Success,
                //    Message = "删除成功"
                //};
            }
            catch (Exception e)
            {
                return new ResultDto { Code = Status.Failed, Message = e.Message };
            }
        }

        #endregion
    }
}
